﻿using MongoDB.Bson;
using System;
using System.Collections.Generic;
namespace hlog {
    public class ObjectUtil {
        public static Object toOb(BsonDocument doc) {
            Dictionary<String ,object> v = new Dictionary<String ,object>();
            IEnumerable<BsonElement> list = doc.Elements;
            foreach( BsonElement e in list ) {
                var val = e.Value;
                if( val.IsBsonDateTime ) {
                    BsonDateTime va = val.AsBsonDateTime;
                    v.Add(e.Name ,va.ToLocalTime());
                }  else {
                    v.Add(e.Name ,e.Value.ToString());
                }
                
           
            }
            return v;
         }
        public static Dictionary<String ,object> toOb2(BsonDocument doc) {
            Dictionary<String ,object> data = new Dictionary<String ,object>();
            IEnumerable<BsonElement> list = doc.Elements;
            foreach( BsonElement e in list ) {
                var v = e.Value;
                if(v.IsBsonDocument) {
                    data.Add(e.Name, toOb2((BsonDocument)v));
                } else if(v.IsBsonArray){
                     BsonArray array = v.AsBsonArray;
                    List<object> l = new List<object>();
                    foreach (BsonValue eChild in array)
                    {
                        if (eChild.IsBsonDocument) {
                            l.Add(toOb2((BsonDocument)eChild));
                        }  else {
                            l.Add(eChild.ToString());
                        }
                     }
                     data.Add(e.Name, l);
                  } else {
                    data.Add(e.Name, v.ToString());
                }
               
            }
            return data;
         }
        public static BsonDocument def(BsonDocument his,BsonDocument nowDoc) {
            BsonDocument bd  = new BsonDocument(); ;
            IEnumerable<BsonElement> elements = nowDoc.Elements;
            foreach (BsonElement be in elements) {
                String name = be.Name;
                BsonValue oldvalue = his[name];
                BsonValue nowv = be.Value;
                var defValue = def2(oldvalue ,nowv,name);
                if( defValue != null) {
                    bd.Add(name ,defValue);
                }
               
            }
            return bd;
        }
        
        static BsonValue def2(BsonValue oldvalue ,BsonValue nowv,String name) {
            if( nowv.IsBsonArray ) {
                BsonArray array = nowv.AsBsonArray;
                BsonArray arrayold = oldvalue.AsBsonArray;
                if( array.Count != arrayold.Count ) {
                  return nowv;
                } else {
                    BsonArray arrayNew = new BsonArray();
                    for( int i = 0;i < array.Count;i++ ) {
                        BsonDocument bdc = def(arrayold[i].AsBsonDocument ,array[i].AsBsonDocument);
                        if( bdc.ElementCount != 0 ) {
                            arrayNew.Add(bdc);
                        }
                    }
                    if( arrayNew.Count != 0 ) {
                        return arrayNew;
                    }
                  
                }
            } else if( nowv.IsBsonDocument ) {
                BsonDocument defValue = def(oldvalue.AsBsonDocument ,nowv.AsBsonDocument);
                if( defValue.ElementCount != 0 ) {
                    return defValue;
                }
            } else {
           
                    return valueChange(oldvalue.ToString() ,nowv.ToString() ,name);
                
               
            }
             return null;
         }
        public static BsonDocument getDoc(BsonDocument doc,string name) {
             if( doc != null && doc.Contains(name) ) {
               return doc[name].AsBsonDocument;
            }
            return null;
        }
         public static String getStr(BsonDocument doc ,string name) {
             if( doc != null && doc.Contains(name) ) {
                return doc[name].ToString();
            }
            return "";
        }

        public static DateTime getDate(BsonDocument doc ,string name) {
            if( doc != null && doc.Contains(name) ) {
                BsonValue bv = doc["ticks"];
                if( bv.IsBsonDateTime ) {
                  return  bv.AsBsonDateTime.ToLocalTime();
                }
              
             }
           throw new Exception(name+"转换日期异常");
        }
        public  static BsonDocument getDef(BsonDocument his ,BsonDocument document ,List<String> nameList ,List<String> nameList2) {
             BsonDocument res = null;
            BsonDocument bd = new BsonDocument();
            foreach( String name in nameList ) {
                String oldvalue = getStr(his ,name);
                String nowv = getStr(document ,name);
                var defValue = valueChange(oldvalue ,nowv ,name);
                if( defValue != null ) {
                    res = bd;
                    bd.Add(name ,defValue);
                } else {
                   // bd.Add(name ,nowv);
                }
             }
            if( res != null ) {
                copyValue(document ,nameList2 ,res);
            }
              return res;
         }

        public static  BsonDocument copyValue(BsonDocument document ,List<String> nameList2 ,BsonDocument res=null) {
            if( res == null ) {
                res = new BsonDocument();

            }
            foreach( String name in nameList2 ) {
                if( document.Contains(name) ) {
                    res.Add(name ,document[name]);
                }
            }
            return res;
        
        }


        public static BsonValue valueChange(String oldvalue ,String nowv ,String name ) {
            if (String.IsNullOrWhiteSpace(oldvalue) && String.IsNullOrWhiteSpace(nowv)) { 
                return null;
            }
            oldvalue = String.IsNullOrWhiteSpace(oldvalue) ? "0" : oldvalue;
            if( oldvalue != nowv ) {
                return BsonValue.Create(oldvalue + "->" + nowv);
            }
            return null;
         }
     }
}
